import React from 'react';
import { Menu, Search } from '@teamix/ui';
import debounce from 'lodash.debounce';
import ListEmpty from 'atComponents/ListEmpty';
import ListLoading from 'atComponents/ListLoading';
import track from 'utils/track';
import { YunxiaoIcon } from '@alife/devops-ui';
import exceed from 'utils/apimap';
import PathEllipsis from 'components/pathEllipsis';
import utils from 'utils';
import { navigate, getPathWithNoRootPath } from 'utils/router';
import './index.scss';
import intl from '../../../locale';

export default class SearcherDropdown extends React.Component {
  constructor(props) {
    super(props);
    this.doSearch = debounce(this.doSearch, 500);
  }

  state = {
    searchText: '',
    list: [],
    loading: true,
  };

  componentDidMount() {
    this.doSearch();
    track({
      action: 'breadcrumb',
      page: 'Ceiling',
    });
  }

  goToPathByAssetsName = async (path) => {
    // 由资源名得到url路径
    const { assetsName } = window.FORCE;
    const key = assetsName.replace('project', '').toLocaleLowerCase();
    let result = key;

    switch (key) {
      case 'blame':
        result = 'file';
        break;
      case 'commitdetail':
      case 'compare':
        result = 'commits';
        break;
      case 'mergerequestdetail':
        result = 'mergerequest';
        break;
      case 'settings':
        result = 'settings';
        break;
      case 'security':
        result = 'security';
        break;
      default:
        break;
    }

    const res = await exceed.fetch({
      api: 'spa.path',
      data: {
        path: getPathWithNoRootPath(`/${path}`),
      },
    });

    if (res && res.success) {
      const { pathResource } = res.result;
      const { defaultBranch, id, isExist, isEmpty } = pathResource;
      const dataSource = [
        {
          key: 'files',
          id: '',
        },
        {
          key: 'commits',
          id: `/commits/${utils.revisionEncodeURI(defaultBranch)}`,
        },
        {
          key: 'branches',
          id: '/branches',
        },
        {
          key: 'tags',
          id: '/tags',
        },
        {
          key: 'mergerequest',
          id: '/merge_requests',
        },
        {
          key: 'pipeline',
          id: '/pipeline',
        },
        {
          key: 'security',
          id: '/project_security',
        },
        {
          key: 'insight',
          id: '/insight',
        },
        {
          key: 'activity',
          id: '/activity',
        },
      ];

      const projectInfo = await exceed.fetch({
        api: 'projects.single.get',
        params: {
          id,
        },
      });
      const isImportUnfinished =
        projectInfo.import_status === 'started' ||
        projectInfo.import_status === 'stopping' ||
        (projectInfo.import_status === 'failed' && isExist === 'false');
      let hiddenKeys = [];
      if (isImportUnfinished) {
        hiddenKeys = [
          'merge',
          'commits',
          'mergerequest',
          'branches',
          'tags',
          'security',
          'pipeline',
          'insight',
        ];
      } else if (isEmpty === 'true') {
        hiddenKeys = ['merge', 'commits', 'branches', 'tags'];
      }

      const shownDataSource = dataSource.filter((item) => {
        return hiddenKeys && !hiddenKeys.includes(item.key);
      });

      const activeId = shownDataSource.find((item) => item.key === result)?.id || '';

      navigate(`/${path}${activeId}`, {
        state: { forceUpdate: true },
      });
    }
  };

  doSearch() {
    const { isInGroup, orgIsParent, parentId } = this.getPathResouceInfo();
    this.setState({
      loading: true,
    });

    // 无父组时，查询都是全部代码组、库；有父组时，都是一个同级组、库

    let projectExtraParams = {};
    let groupExtraParams = {};
    let groupExtraData = {};
    if (!orgIsParent) {
      projectExtraParams = {
        id: parentId,
        order_by: 'updated_at',
      };

      groupExtraParams = {
        id: parentId,
      };
    } else {
      groupExtraData = {
        ceiling_search: true,
      };
    }

    const listPromise = isInGroup
      ? exceed.fetch({
          api: orgIsParent ? 'groups.all.list' : 'group.subgroups.list',
          data: {
            page: 1,
            per_page: 5,
            order_by: 'updated_at',
            search: this.state.searchText,
            parent_id: parentId,
            ...groupExtraData,
          },

          params: groupExtraParams,
        })
      : exceed.fetch({
          api: orgIsParent ? 'projects.exploreList' : 'group.projects',
          data: {
            search: this.state.searchText,
            per_page: 5,
            page: 1,
            exact_match: this.state.searchText !== '',
          },

          params: projectExtraParams,
        });

    listPromise
      .then((result) => {
        result.shift();
        this.setState({
          list: result,
          loading: false,
        });
      })
      .catch((err) => {
        console.error(err);
      });
  }

  onChange = (value) => {
    this.setState(
      {
        searchText: value,
      },

      () => {
        this.doSearch();
      },
    );
  };

  renderEmpty = () => {
    return (
      <ListEmpty
        imgType="search"
        desc={intl.get({
          id: 'code-assets.initNavigation.breadcrumbOverlay.dropdown.NoSearchResults',
          defaultMessage: '无搜索结果',
        })}
        style={{ padding: '12px 0px' }}
      />
    );
  };

  getPathResouceInfo = () => {
    const { pathResource, organization } = window.FORCE;
    const isInGroup =
      pathResource &&
      pathResource.id &&
      pathResource.type &&
      pathResource.type.toLowerCase() === 'group';
    const orgIsParent = pathResource.parentId === organization.namespace_id;

    let label = '';
    if (isInGroup) {
      label = orgIsParent
        ? intl.get({
            id: 'code-assets.initNavigation.breadcrumbOverlay.dropdown.LastUpdated',
            defaultMessage: '最近更新',
          })
        : intl.get({
            id: 'code-assets.initNavigation.breadcrumbOverlay.dropdown.PeerCodeGroupsRecentUpdates',
            defaultMessage: '同级代码组 · 最近更新',
          });
    } else {
      label = orgIsParent
        ? intl.get({
            id: 'code-assets.initNavigation.breadcrumbOverlay.dropdown.LastUpdated',
            defaultMessage: '最近更新',
          })
        : intl.get({
            id: 'code-assets.initNavigation.breadcrumbOverlay.dropdown.PeerCodeLibraryRecentUpdates',
            defaultMessage: '同级代码库 · 最近更新',
          });
    }

    return {
      // 组内
      isInGroup,
      // 一级组或库
      orgIsParent,
      // 当前库、组id
      curId: pathResource.id,
      parentId: pathResource.parentId,
      organization,
      label,
    };
  };

  renderList = () => {
    const { isInGroup, curId, orgIsParent } = this.getPathResouceInfo();

    const { list, searchText } = this.state;

    if (!list) {
      return null;
    }

    if (!list.length && searchText) {
      return this.renderEmpty();
    }
    return (
      <Menu.Group label={null} key="groups" style={{ display: 'none' }}>
        {list.map((item) => (
          <Menu.Item key={item.id}>
            <div
              className="nav-breadcrumb-item"
              onClick={() => {
                // 如果选择的代码组，则直接跳转路由，如果是库，则判断资源tab
                if (isInGroup) {
                  window.FORCE.pathResource.projectInfo = null;
                  navigate(`/${item.path_with_namespace}`, {
                    state: { forceUpdate: true },
                  });
                } else {
                  this.goToPathByAssetsName(item.path_with_namespace);
                }
              }}
            >
              <div className="nav-breadcrumb-item-left">
                {Number(curId) === Number(item.id) ? (
                  <YunxiaoIcon type="true-line" className="select-icon" />
                ) : null}
              </div>
              <div className="nav-breadcrumb-item-right">
                <React.Fragment>
                  {isInGroup ? (
                    <span className="search-group-icon">
                      <YunxiaoIcon type="folder-line" />
                    </span>
                  ) : (
                    <span className="search-repo-icon">
                      <YunxiaoIcon type="code-basement-line" />
                    </span>
                  )}

                  <PathEllipsis
                    path={orgIsParent ? utils.getGroupPath(item.name_with_namespace) : item.name}
                    style={{ width: 220 }}
                  />
                </React.Fragment>
              </div>
            </div>
          </Menu.Item>
        ))}
      </Menu.Group>
    );
  };

  render() {
    const { list, loading, searchText } = this.state;

    const { isInGroup, label } = this.getPathResouceInfo();

    const searchInput = (
      <div className="breadcrumb-select-search">
        <Search
          shape="simple"
          autoFocus
          placeholder={
            isInGroup
              ? intl.get({
                  id: 'code-assets.initNavigation.breadcrumbOverlay.dropdown.SearchForCodeGroups',
                  defaultMessage: '搜索代码组',
                })
              : intl.get({
                  id: 'code-assets.initNavigation.breadcrumbOverlay.dropdown.SearchCodeBase',
                  defaultMessage: '搜索代码库',
                })
          }
          value={searchText}
          onChange={this.onChange}
          style={{ width: '100%' }}
        />
      </div>
    );

    if (loading) {
      return (
        <div className="history-overlay breadcrumb-overlay">
          {searchInput}
          <ListLoading style={{ padding: '12px 0px' }} />
        </div>
      );
    }

    if (!list.length) {
      return (
        <div className="history-overlay breadcrumb-overlay">
          {searchInput}
          {this.renderEmpty()}
        </div>
      );
    }

    return (
      <div className="history-overlay breadcrumb-overlay">
        {searchInput}
        <Menu size="small" autoFocus={false}>
          <Menu.Group label={label}>
            {[].map(() => {
              return <Menu.Item />;
            })}
          </Menu.Group>
          {this.renderList()}
        </Menu>
      </div>
    );
  }
}
